package controller;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import model.PriorityListItem;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import utils.Utils;
import android.app.Activity;
import android.content.Context;
import android.database.DataSetObserver;
import android.os.AsyncTask;
import android.os.CountDownTimer;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import app.cloudstringers.Home;
import app.cloudstringers.PriorityList;
import app.cloudstringers.R;

import com.mobeta.android.dslv.DragSortListView;

import define.API;
import define.Constants;
import define.Key;

/**
 * Apply only for Upload class and Convert class
 */
public class PriorityListAsync extends AsyncTask<String, Void, Boolean> {
	/**
	 * String section
	 */
	private boolean IS_HIDE_DIALOG = false;
	private boolean IS_STACK_OVER_FLOW = false;
	public static boolean IS_STOP = false;
	public static boolean IS_SUBMIT = false;
	private boolean IS_SUDDENLY_DISCONNECTED = false;

	private String CHANGED_STATUS = "";
	public static String CURRENT_STATUS_HB = null;
	private String ID = null;
	private String STATUS = null;
	private String STOPPED = "";

	private static final String TAG = PriorityListAsync.class.getSimpleName();

	/**
	 * Data section
	 */
	public static LinkedList<PriorityListItem> mLlItems = new LinkedList<PriorityListItem>();
	public static PriorityListItemAdapter refreshPriorityListItemAdapter = null;

	/**
	 * View section
	 */
	private DragSortListView dragSortLvPriorityList;

	/**
	 * Others section
	 */
	private Context context;

	// onDropListener
	private DragSortListView.DropListener onDropListener = new DragSortListView.DropListener() {
		@Override
		public void drop(int from, int to) {
			PriorityListItem item = refreshPriorityListItemAdapter
					.getItem(from);

			refreshPriorityListItemAdapter.notifyDataSetChanged();
			refreshPriorityListItemAdapter.remove(item);
			refreshPriorityListItemAdapter.insert(item, to);
		}
	};

	// onDragListener
	private DragSortListView.DragScrollProfile onDragListener = new DragSortListView.DragScrollProfile() {
		@Override
		public float getSpeed(float w, long t) {
			if (w > 0.8f) {
				// Traverse all views in a millisecond
				return (refreshPriorityListItemAdapter.getCount()) / 0.001f;
			} else {
				return 10.0f * w;
			}
		}
	};

	/**
	 * Timer counter
	 * 
	 * @author Administrator
	 * 
	 */
	public class TimeoutTimer extends CountDownTimer {

		public TimeoutTimer(long millisInFuture, long countDownInterval) {
			super(millisInFuture, countDownInterval);
		}

		@Override
		public void onTick(long millisUntilFinished) {
		}

		@Override
		public void onFinish() {
			define.PriorityList.IS_TIME_OUT = true;
		}
	}

	public PriorityListAsync(Context context) {
		this.context = context;

		/**
		 * Set time out 30s after pressed Submit button once
		 */
		if (IS_SUBMIT || PriorityList.IS_CHANGE_PRIORITY_IN_CONNECTED_STATE) {
			if (define.PriorityList.timeoutTimer == null) {
				define.PriorityList.timeoutTimer = new TimeoutTimer(
						define.PriorityList.TIME_OUT,
						define.PriorityList.COUNTDOWN_TIME_OUT);
				define.PriorityList.timeoutTimer.start();
			} else {
				define.PriorityList.timeoutTimer.cancel();
				define.PriorityList.timeoutTimer = null;

				define.PriorityList.timeoutTimer = new TimeoutTimer(
						define.PriorityList.TIME_OUT,
						define.PriorityList.COUNTDOWN_TIME_OUT);
				define.PriorityList.timeoutTimer.start();
			}
		}

		/**
		 * Adapter to show the list item
		 */
		refreshPriorityListItemAdapter = new PriorityListItemAdapter(context,
				R.layout.simple_list_item_priority_list, mLlItems);
	}

	@Override
	protected Boolean doInBackground(String... params) {
		ID = params[0];
		STATUS = params[1];

		return getData(context, ID, Integer.valueOf(STATUS));
	}

	@Override
	protected void onPreExecute() {
		super.onPreExecute();

		((Activity) context).runOnUiThread(new Runnable() {

			@Override
			public void run() {
				Constants.utils.showProgressDialog();

				if (!IS_SUBMIT & mLlItems != null & !mLlItems.isEmpty()) {
					mLlItems.clear();
				}

				// Initialize variables
				dragSortLvPriorityList = (DragSortListView) ((Activity) context)
						.findViewById(R.id.lv_in_priority_list);

				// Set drag & drop listener for list view
				dragSortLvPriorityList.setDropListener(onDropListener);
				dragSortLvPriorityList.setDragScrollProfile(onDragListener);
			}
		});
	}

	@Override
	protected void onPostExecute(final Boolean result) {
		super.onPostExecute(result);

		// Toast.makeText(context, NOTIFICATION, Toast.LENGTH_SHORT).show();

		/**
		 * Check IS_CARD_CONNECTED to show correctly
		 */
		((Activity) context).runOnUiThread(new Runnable() {

			@Override
			public void run() {
				if (result) {
					/**
					 * If RESULT is true
					 */
					if (define.PriorityList.IS_CARD_CONNECTED) {
						/**
						 * Card connected
						 */

						connectedCard();

						showData();
					} else {
						/**
						 * Card was disconnected
						 */

						disconnectedCard();
					}
				} else {
					/**
					 * If Result return false.
					 */
					if (define.PriorityList.IS_TIME_OUT) {
						if (define.PriorityList.IS_CARD_CONNECTED) {
							// Show message
							Toast.makeText(
									context,
									context.getString(R.string.toast_request_time_out),
									Toast.LENGTH_SHORT).show();

							// Set this value = true to hide the progress dialog
							// in Priority List tab
							IS_HIDE_DIALOG = true;

							/**
							 * Reset all things
							 */

							define.PriorityList.IS_SUBMITTED = false;
							define.PriorityList.IS_TIME_OUT = false;
							IS_STOP = false;
							IS_SUBMIT = false;

							// Clear the list
							if (PriorityListAsync.mLlItems != null
									& !PriorityListAsync.mLlItems.isEmpty()) {
								PriorityListAsync.mLlItems.clear();
							}

							new PriorityListAsync(context)
									.execute(
											ID,
											define.Status.STATUS_GET_LIST_OF_FILES
													+ "");
						}
					} else {
						Constants.utils.showConnectionTimeoutDialog(
								context, Home.class);
					}
				}

				/**
				 * If STACKOVERFLOW exception happens, reload the list
				 */
				if (IS_STACK_OVER_FLOW) {
					// Clear the list
					if (PriorityListAsync.mLlItems != null
							& !PriorityListAsync.mLlItems.isEmpty()) {
						PriorityListAsync.mLlItems.clear();
					}

					new PriorityListAsync(context).execute(ID,
							define.Status.STATUS_GET_LIST_OF_FILES + "");
				}

				Constants.utils.hideProgressDialog();

				// Enable all tab widget
				Utils
						.enableTabWidgetInStatusTab(Constants.STATUS_TAB_SIZE);

				// Hide progress dialog
				if (IS_HIDE_DIALOG) {
					if (PriorityList.mPdWaiting != null
							&& PriorityList.mPdWaiting.isShowing()) {
						PriorityList.mPdWaiting.dismiss();
						PriorityList.mPdWaiting = null;
					}
				}
			}
		});
	}

	/**
	 * Basic methods
	 */

	private void connectedCard() {
		// Hide Card was connected text
		PriorityList.mTvCardStatus.setVisibility(View.GONE);

		if (STATUS.equals(define.Status.STATUS_GET_LIST_OF_FILES)) {
			// Hide Change Priority button, Show Submit button
			PriorityList.mIbtnChangePriority.setVisibility(View.VISIBLE);
			PriorityList.mIbtnSubmit.setVisibility(View.GONE);
		}
		if (CHANGED_STATUS.equals(Constants.INIT)) {
			if (PriorityList.IS_CHANGE_STATE) {
				// Hide Change Priority button, Show Submit
				// button
				PriorityList.mIbtnChangePriority.setVisibility(View.VISIBLE);
				PriorityList.mIbtnSubmit.setVisibility(View.GONE);

				PriorityList.IS_CHANGE_STATE = false;
			} else {
				// Hide Change Priority button, Show Submit
				// button
				PriorityList.mIbtnChangePriority.setVisibility(View.GONE);
				PriorityList.mIbtnSubmit.setVisibility(View.VISIBLE);
			}
		}

		if (IS_SUBMIT) {
			// Show Change Priority button, Hide Submit button
			PriorityList.mIbtnChangePriority.setVisibility(View.VISIBLE);
			PriorityList.mIbtnSubmit.setVisibility(View.GONE);

			// If timer still be existed, should set null
			if (define.PriorityList.timeoutTimer != null) {
				define.PriorityList.timeoutTimer.cancel();
				define.PriorityList.timeoutTimer = null;
			}
		}

		if (STOPPED.equals(Constants.STOPPED)) {
			// Show Submit button, Hide Change Priority button
			PriorityList.mIbtnChangePriority.setVisibility(View.GONE);
			PriorityList.mIbtnSubmit.setVisibility(View.VISIBLE);
		}

		// If STACKOVERFLOW exception happens,
		if (IS_STACK_OVER_FLOW) {
			// Show Submit button, Hide Change Priority button
			PriorityList.mIbtnChangePriority.setVisibility(View.GONE);
			PriorityList.mIbtnSubmit.setVisibility(View.VISIBLE);
		}

		// Can not move the file
		// Not show refresh button when Change Priority button was shown
		CheckHBAsync.avoidChangeFileOrder();
		CheckHBAsync.avoidShowRefreshButton();

		if (define.PriorityList.IS_SUBMITTED) {
			// Clear the list first
			if (mLlItems != null & !mLlItems.isEmpty()) {
				mLlItems.clear();
			}

			// If already submitted
			// Call API again to check
			// The server already updated new list of files
			new PriorityListAsync(context).execute(ID,
					define.Status.STATUS_GET_LIST_OF_FILES + "");
		}
	}

	private void disconnectedCard() {
		// Hide the progress dialog
		IS_HIDE_DIALOG = true;

		// Show Card was disconnected state
		PriorityList.mTvCardStatus.setVisibility(View.VISIBLE);
		PriorityList.mTvCardStatus.setText(context
				.getString(R.string.card_is_disconnected));

		/**
		 * In the first time, show Change Priority button first, hide Submit
		 * button first
		 */
		if (PriorityList.IS_FIRST_TIME_TO_PRIORITY_LIST) {
			// Show Change Priority button, Hide Submit button
			PriorityList.mIbtnChangePriority.setVisibility(View.VISIBLE);
			PriorityList.mIbtnSubmit.setVisibility(View.GONE);

			PriorityList.IS_FIRST_TIME_TO_PRIORITY_LIST = false;
		} else {
			if (!CheckHBAsync.IS_FROM_CHECK_HB_TO_PRIORITY_LIST
					| PriorityList.IS_CHANGE_PRIORITY_IN_DISCONNECTED_STATE) {
				// Show Submit button, Hide Change Priority
				// button
				PriorityList.mIbtnChangePriority.setVisibility(View.GONE);
				PriorityList.mIbtnSubmit.setVisibility(View.VISIBLE);

				// Reset all things
				PriorityList.IS_CHANGE_PRIORITY_IN_DISCONNECTED_STATE = false;
			}
		}

		// If STACKOVERFLOW exception happens,
		if (IS_STACK_OVER_FLOW) {
			// Show Submit button, Hide Change Priority button
			PriorityList.mIbtnChangePriority.setVisibility(View.GONE);
			PriorityList.mIbtnSubmit.setVisibility(View.VISIBLE);
		}

		// Can not move the file
		// Not show refresh button when Change Priority button was shown
		CheckHBAsync.avoidChangeFileOrder();
		CheckHBAsync.avoidShowRefreshButton();

		// Show data
		showData();

		/**
		 * If while stopping and receiving status=stopped card suddenly is
		 * disconnected call new thread to received the new list
		 */
		if (IS_STOP) {
			IS_STOP = false;

			// Clear the list first
			if (mLlItems != null & !mLlItems.isEmpty()) {
				mLlItems.clear();
			}

			// Call API again to check
			// The server already updated new list of files
			new PriorityListAsync(context).execute(ID,
					define.Status.STATUS_GET_LIST_OF_FILES + "");
		}

		/**
		 * If card suddenly was disconnected while submitting, Reload the page
		 */
		if (IS_SUDDENLY_DISCONNECTED) {
			IS_SUDDENLY_DISCONNECTED = false;

			// Clear the list first
			if (mLlItems != null & !mLlItems.isEmpty()) {
				mLlItems.clear();
			}

			// Call API again to check
			// The server already updated new list of files
			new PriorityListAsync(context).execute(ID,
					define.Status.STATUS_GET_LIST_OF_FILES + "");
		}
	}

	public boolean getData(Context context, String ID, int KEY_STATUS) {
		try {
			HttpClient mHttpClient = new DefaultHttpClient();

			HttpPost mHttpPost = null;
			switch (KEY_STATUS) {
			case define.Status.STATUS_SUBMIT:
				mHttpPost = new HttpPost(API.UPLOAD_LIST_REQUEST);
				break;
			case define.Status.STATUS_STOP:
				if (!IS_STOP) {
					mHttpPost = new HttpPost(API.UPLOAD_LIST_REQUEST);
				} else {
					mHttpPost = new HttpPost(API.DOWNLOAD_LIST_REQUEST);
				}
				break;
			default:
				mHttpPost = new HttpPost(API.DOWNLOAD_LIST_REQUEST);
				break;
			}

			List<NameValuePair> mNameValues = new ArrayList<NameValuePair>(2);

			/**
			 * Get HB
			 */
			// 1.user_id
			mNameValues.add(new BasicNameValuePair(Key.KEY_USER_ID, ID));

			// 2.status=
			switch (KEY_STATUS) {
			case define.Status.STATUS_STOP:
				if (context.getClass().getSimpleName()
						.equals(define.Class.CLASS_PRIORITY_LIST)) {
					if (!IS_STOP) {
						// 2.status=Stop
						mNameValues.add(new BasicNameValuePair(Key.KEY_STATUS,
								Constants.STOP + ""));
					}
				}

				break;
			case define.Status.STATUS_SUBMIT:
				// 2.status=Submit

				// status=submit
				// num_videos
				// file_list : file name, date, pause flag
				if (context.getClass().getSimpleName()
						.equals(define.Class.CLASS_PRIORITY_LIST)) {
					mNameValues.add(new BasicNameValuePair(Key.KEY_STATUS,
							Constants.SUBMIT + ""));
					mNameValues.add(new BasicNameValuePair(Key.KEY_NUM_VIDEOS,
							mLlItems.size() + ""));

					StringBuilder mSb = new StringBuilder();
					for (int i = 0; i < mLlItems.size(); i++) {
						// Add to String Builder
						// for get data to submit to the server
						if (i == mLlItems.size() - 1) {
							mSb.append(mLlItems.get(i).getFileName() + ","
									+ mLlItems.get(i).getTotalSize() + ","
									+ mLlItems.get(i).getPauseValue());
						} else {
							mSb.append(mLlItems.get(i).getFileName() + ","
									+ mLlItems.get(i).getTotalSize() + ","
									+ mLlItems.get(i).getPauseValue() + ",");
						}
					}

					mNameValues.add(new BasicNameValuePair(Key.KEY_FILE_LIST,
							mSb.toString() + ""));
				}
				break;
			default:
				break;
			}

			mHttpPost.setEntity(new UrlEncodedFormEntity(mNameValues));

			HttpResponse mHttpResponse = mHttpClient.execute(mHttpPost);
			HttpEntity mHttpEntity = mHttpResponse.getEntity();

			String XML = EntityUtils.toString(mHttpEntity);

			if (define.PriorityList.IS_TIME_OUT) {
				return false;
			}

			if (XML == null) {
				//return false;
				Toast.makeText(context, context.getString(R.string.toast_user_may_not_have_a_card), Toast.LENGTH_LONG).show();
			}

			splitData(KEY_STATUS, XML);

			/**
			 * Check time out in here If pass 30 seconds, show notification to
			 * notify the user should try again
			 */
			if (define.PriorityList.IS_TIME_OUT) {
				return false;
			}

			return true;
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return false;
		} catch (ClientProtocolException e) {
			e.printStackTrace();
			return false;
		} catch (ConnectTimeoutException e) {
			e.printStackTrace();
			return false;
		} catch (SocketException e) {
			e.printStackTrace();
			return false;
		} catch (SocketTimeoutException e) {
			e.printStackTrace();
			return false;
		} catch (StackOverflowError e) {
			IS_STACK_OVER_FLOW = true;

			e.printStackTrace();
			return false;
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	}

	private void showData() {
		if (refreshPriorityListItemAdapter != null
				&& !refreshPriorityListItemAdapter.isEmpty()) {
			// Set adapter for list
			try {
				dragSortLvPriorityList
						.setAdapter(refreshPriorityListItemAdapter);
			} catch (Exception e) {
				// Clear the list first
				if (mLlItems != null & !mLlItems.isEmpty()) {

					mLlItems.clear();
				}

				// Call API again to check
				// The server already updated new list of files
				new PriorityListAsync(context).execute(ID,
						define.Status.STATUS_GET_LIST_OF_FILES + "");
			}
			refreshPriorityListItemAdapter.notifyDataSetChanged();
		} else {
			// If adapter is null
			refreshPriorityListItemAdapter = new PriorityListItemAdapter(
					context, R.layout.simple_list_item_priority_list, mLlItems);

			try {
				dragSortLvPriorityList
						.setAdapter(refreshPriorityListItemAdapter);
			} catch (Exception e) {
				// Clear the list first
				if (mLlItems != null & !mLlItems.isEmpty()) {
					mLlItems.clear();
				}

				// Call API again to check
				// The server already updated new list of files
				new PriorityListAsync(context).execute(ID,
						define.Status.STATUS_GET_LIST_OF_FILES + "");
			}
			refreshPriorityListItemAdapter.notifyDataSetChanged();

			refreshPriorityListItemAdapter = null;
		}
	}

	private void splitData(int KEY_STATUS, String XML) {
		switch (KEY_STATUS) {
		case define.Status.STATUS_HB:
			// 2.status=HB
			if (context.getClass().getSimpleName()
					.equals(define.Class.CLASS_PRIORITY_LIST)) {
				mLlItems.clear();

				String[] XML_PLITTER = XML.split(",");

				/**
				 * Set IS_CARD_CONNECTED=true to hide "Card was disconnected"
				 * Bar
				 */
				CURRENT_STATUS_HB = XML_PLITTER[0].split(":")[1];
				if (CURRENT_STATUS_HB.equals(define.Status.STATUS_HB_CONNECTED
						+ "")) {
					define.PriorityList.IS_CARD_CONNECTED = true;
				} else {
					define.PriorityList.IS_CARD_CONNECTED = false;
				}

				// Length = 21
				for (int i = 3; i < 21; i += 6) {
					// new item with data : file name, total size, upload date,
					// pause, last modified date, state
					PriorityListItem priorityListItem = new PriorityListItem(
							XML_PLITTER[i], XML_PLITTER[i + 1],
							XML_PLITTER[i + 2], XML_PLITTER[i + 3],
							XML_PLITTER[i + 4], XML_PLITTER[i + 5]);

					// Add to priority list item array
					mLlItems.addLast(priorityListItem);
				}
			}
			break;
		case define.Status.STATUS_STOP:
			// 2.status=Stop
			if (context.getClass().getSimpleName()
					.equals(define.Class.CLASS_PRIORITY_LIST)) {
				/**
				 * TODO When the server has not response "...status=stopped..."
				 * still show loading process
				 */
				if (!IS_STOP) {
					IS_STOP = true;

					// Continue wait for loading process
					// until the server response "...status=stopped..."
					if (!define.PriorityList.IS_TIME_OUT) {
						getData(context, ID, Integer.valueOf(STATUS));
					}
				} else {
					String[] XML_PLITTER = XML.split(",");

					/**
					 * Set IS_CARD_CONNECTED=true to hide
					 * "Card was disconnected" Bar
					 */
					CURRENT_STATUS_HB = XML_PLITTER[0].split(":")[1];
					if (CURRENT_STATUS_HB
							.equals(define.Status.STATUS_HB_CONNECTED + "")) {
						define.PriorityList.IS_CARD_CONNECTED = true;

						STOPPED = XML_PLITTER[1].split(":")[1];
						if (STOPPED.equals(Constants.STOPPED)) {
							/**
							 * If Card already stopped, Reset all things, Stop
							 * timer count down also
							 */
							IS_STOP = false;
							PriorityList.IS_CHANGE_PRIORITY_IN_CONNECTED_STATE = false;

							// Cancel Time Out count down timer
							if (define.PriorityList.timeoutTimer != null) {
								define.PriorityList.timeoutTimer.cancel();
								define.PriorityList.timeoutTimer = null;
							}

							// Clear old list
							mLlItems.clear();

							for (int i = 3; i < XML_PLITTER.length; i += 6) {
								// new item with data : file name, total size,
								// upload
								// date,
								// pause, last modified date, state
								PriorityListItem priorityListItem = new PriorityListItem(
										XML_PLITTER[i], XML_PLITTER[i + 1],
										XML_PLITTER[i + 2], XML_PLITTER[i + 3],
										XML_PLITTER[i + 4], XML_PLITTER[i + 5]);

								// Add to priority list item array
								mLlItems.addLast(priorityListItem);
							}
						} else {
							// Continue wait for loading process
							// until the server response "...status=stopped..."
							if (!define.PriorityList.IS_TIME_OUT) {
								getData(context, ID, Integer.valueOf(STATUS));
							}
						}
					} else {
						define.PriorityList.IS_CARD_CONNECTED = false;
					}
				}
			}
			break;
		case define.Status.STATUS_SUBMIT:
			// 2.status=Submit
			if (context.getClass().getSimpleName()
					.equals(define.Class.CLASS_PRIORITY_LIST)) {
				define.PriorityList.IS_SUBMITTED = true;

				// Set this boolean is false to avoid create Timeout Timer twice
				// Also set from beginning
				IS_SUBMIT = false;
			}
			break;
		default:
			if (define.PriorityList.IS_SUBMITTED) {
				/**
				 * 2.status=submit
				 */

				/**
				 * Need wait for the server response the "...status=init..." It
				 * means the list of files already submitted
				 */

				mLlItems.clear();

				String[] XML_PLITTER = XML.split(",");

				if (!IS_SUBMIT & define.PriorityList.IS_SUBMITTED
						& Integer.valueOf(XML_PLITTER[0].split(":")[1]) == 0
						& XML_PLITTER[1].split(":")[1].equals(Constants.INIT)) {
					IS_SUDDENLY_DISCONNECTED = true;
				}

				/**
				 * Set IS_CARD_CONNECTED=true to hide "Card was disconnected"
				 * Bar
				 */
				CURRENT_STATUS_HB = XML_PLITTER[0].split(":")[1];
				if (CURRENT_STATUS_HB.equals(define.Status.STATUS_HB_CONNECTED
						+ "")) {
					define.PriorityList.IS_CARD_CONNECTED = true;

					if (XML_PLITTER[1].split(":")[1].equals(Constants.INIT)) {
						for (int i = 3; i < XML_PLITTER.length; i += 6) {
							// new item with data : file name, total size,
							// upload
							// date, pause, last modified date, state
							PriorityListItem priorityListItem = new PriorityListItem(
									XML_PLITTER[i], XML_PLITTER[i + 1],
									XML_PLITTER[i + 2], XML_PLITTER[i + 3],
									XML_PLITTER[i + 4], XML_PLITTER[i + 5]);

							// Add to priority list item array
							mLlItems.addLast(priorityListItem);
						}

						// Hide dialog in Priority List page
						// after already submitted to the server
						IS_HIDE_DIALOG = true;

						// Set this value = true to show Change Priority button
						// again
						IS_SUBMIT = true;

						// Reset
						define.PriorityList.IS_SUBMITTED = false;
					} else {
						// Continue wait for loading process
						// until the server response "...status=init..."
						STATUS = define.Status.STATUS_GET_LIST_OF_FILES + "";
						getData(context, ID, Integer.valueOf(STATUS));
					}
				} else {
					define.PriorityList.IS_CARD_CONNECTED = false;

					// Reset
					define.PriorityList.IS_SUBMITTED = false;
				}
			} else {
				/**
				 * 2.status=GET_LIST_OF_FILES
				 */
				if (context.getClass().getSimpleName()
						.equals(define.Class.CLASS_PRIORITY_LIST)) {
					String[] XML_PLITTER = XML.split(",");

					/**
					 * If get HB=1 Need hide "Card was disconnected" bar
					 */
					/**
					 * Set IS_CARD_CONNECTED=true to hide
					 * "Card was disconnected" Bar
					 */
					CURRENT_STATUS_HB = XML_PLITTER[0].split(":")[1];
					CHANGED_STATUS = XML_PLITTER[1].split(":")[1];
					if (CURRENT_STATUS_HB
							.equals(define.Status.STATUS_HB_CONNECTED + "")) {
						define.PriorityList.IS_CARD_CONNECTED = true;

						/**
						 * Set Change State value is true
						 */
						PriorityList.IS_CHANGE_STATE = true;
					} else {
						define.PriorityList.IS_CARD_CONNECTED = false;

						/**
						 * Set Change State value is false
						 */
						PriorityList.IS_CHANGE_STATE = false;
					}

					for (int i = 3; i < XML_PLITTER.length; i += 6) {
						// new item with data : file name, total size, upload
						// date,
						// pause, last modified date, state
						PriorityListItem priorityListItem = new PriorityListItem(
								XML_PLITTER[i], XML_PLITTER[i + 1],
								XML_PLITTER[i + 2], XML_PLITTER[i + 3],
								XML_PLITTER[i + 4], XML_PLITTER[i + 5]);

						// Add to priority list item array
						mLlItems.addLast(priorityListItem);
					}
				}
			}
			break;
		}
	}

	public class PriorityListItemAdapter extends ArrayAdapter<PriorityListItem> {
		/**
		 * String section
		 */
		private int textViewResourceId;

		private String TAG_PAUSE = "ibtn_pause_";
		private String TAG_PAUSED = "tv_paused_";
		private String TAG_PRIORITY = "ibtn_priority_";
		private String TAG_RESUME = "ibtn_resume_";
		private String TAG_STATE = "iv_state_";

		/**
		 * Data section
		 */
		private LinkedList<PriorityListItem> mLlItem = null;

		/**
		 * View section
		 */
		private class ViewHolder {
			private ImageButton mIbtnPause;
			private ImageButton mIbtnPriority;
			private ImageButton mIbtnResume;
			private ImageView mIvState;
			private TextView mTvContent;
			private TextView mTvManufacturer;
			private TextView mTvPaused;
			private TextView mTvTotalSize;
			private TextView mTvTitle;
		}

		/**
		 * Others section
		 */
		private Context context;

		public PriorityListItemAdapter(Context context, int textViewResourceId,
				LinkedList<PriorityListItem> mLlItems) {
			super(context, textViewResourceId, mLlItems);

			this.context = context;
			this.mLlItem = mLlItems;
			this.textViewResourceId = textViewResourceId;
		}

		@Override
		public View getView(final int position, View convertView,
				final ViewGroup parent) {
			ViewHolder viewHolder = null;
			LinearLayout mLlFunction = null;
			// Initialize variables
			if (convertView == null) {
				viewHolder = new ViewHolder();
				LayoutInflater mLiInflater = (LayoutInflater) context
						.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

				convertView = mLiInflater.inflate(textViewResourceId, null);
				convertView.setLayoutParams(new AbsListView.LayoutParams(
						ViewGroup.LayoutParams.FILL_PARENT,
						ViewGroup.LayoutParams.WRAP_CONTENT));

				mLlFunction = (LinearLayout) convertView
						.findViewById(R.id.ll_function_simple_list_item);

				viewHolder.mIbtnPause = (ImageButton) convertView
						.findViewById(R.id.ibtn_pause_item_in_status);
				viewHolder.mIbtnPriority = (ImageButton) convertView
						.findViewById(R.id.ibtn_set_priority_item_in_priority_list);
				viewHolder.mIbtnResume = (ImageButton) convertView
						.findViewById(R.id.ibtn_resume_item_in_priority_list);
				viewHolder.mIvState = (ImageView) convertView
						.findViewById(R.id.iv_state_item_in_priority_list);
				viewHolder.mTvContent = (TextView) convertView
						.findViewById(R.id.tv_content_item_in_priority_list);
				viewHolder.mTvManufacturer = (TextView) convertView
						.findViewById(R.id.tv_manufacturer_item_in_priority_list);
				viewHolder.mTvPaused = (TextView) convertView
						.findViewById(R.id.tv_paused_item_in_priority_list);
				viewHolder.mTvTotalSize = (TextView) convertView
						.findViewById(R.id.tv_total_size_in_priority_list);
				viewHolder.mTvTitle = (TextView) convertView
						.findViewById(R.id.tv_title_item_in_priority_list);

				// Set tag for Priority button, Paused text and Resume button
				// Set tag for pause button
				viewHolder.mIbtnPause.setTag(TAG_PAUSE + position);
				viewHolder.mIbtnPriority.setTag(TAG_PRIORITY + position);
				viewHolder.mIbtnResume.setTag(TAG_RESUME + position);
				viewHolder.mIvState.setTag(TAG_STATE + position);
				viewHolder.mTvPaused.setTag(TAG_PAUSED + position);

				// Hide priority button in the first line
				if (position == 0) {
					viewHolder.mIbtnPriority.findViewWithTag(
							TAG_PRIORITY + position).setVisibility(
							View.INVISIBLE);
				}

				convertView.setTag(viewHolder);
			} else {
				viewHolder = (ViewHolder) convertView.getTag();

				// Always get Linear Layout variable to call from another
				// Activity
				// effectively
				mLlFunction = (LinearLayout) convertView
						.findViewById(R.id.ll_function_simple_list_item);

				viewHolder.mIbtnPause.setTag(TAG_PAUSE + position);
				viewHolder.mIbtnPriority.setTag(TAG_PRIORITY + position);
				viewHolder.mIbtnResume.setTag(TAG_RESUME + position);
				viewHolder.mIvState.setTag(TAG_STATE + position);
				viewHolder.mTvPaused.setTag(TAG_PAUSED + position);
				/**
				 * * priority when pressed will bring the video to top of the
				 * list (top row) For first row, priority Button is not enabled
				 */
				// After clicked Priority Button,
				// Hide priority button in the first line
				// The others is not
				if (position == 0) {
					viewHolder.mIbtnPriority.findViewWithTag(
							TAG_PRIORITY + position).setVisibility(
							View.INVISIBLE);
				} else {
					viewHolder.mIbtnPriority.findViewWithTag(
							TAG_PRIORITY + position)
							.setVisibility(View.VISIBLE);
				}
			}

			/**
			 * Show : Pause button, Paused text, Resume button, Priority button
			 * or not
			 */
			if (PriorityList.mIbtnChangePriority.isShown()) {
				mLlFunction.setVisibility(View.INVISIBLE);
			} else if (PriorityList.mIbtnSubmit.isShown()) {
				mLlFunction.setVisibility(View.VISIBLE);
			}

			// Set data
			/**
			 * Other than using priority user can long hold to row, drag and
			 * drop row to change the upload order
			 */
			final PriorityListItem priorityListItem = mLlItem.get(position);
			if (priorityListItem != null) {
				/**
				 * Set state : video or photo
				 */
				if (priorityListItem.getState().equals(
						define.PriorityList.STATE_VIDEO)) {
					// Video
					viewHolder.mIvState.findViewWithTag(TAG_STATE + position)
							.setBackgroundResource(R.drawable.ic_video_normal);
				} else {
					// Photo
					viewHolder.mIvState.findViewWithTag(TAG_STATE + position)
							.setBackgroundResource(R.drawable.ic_photo_normal);
				}

				String[] SPLIT_DATA = priorityListItem.getFileName().split("/");

				/**
				 * Set manufacturer
				 */
				viewHolder.mTvManufacturer.setText(SPLIT_DATA[0]);

				/**
				 * Set title
				 */
				viewHolder.mTvTitle.setText(SPLIT_DATA[1]);

				/**
				 * Set upload date
				 */
				if (priorityListItem.getLastModifiedDate().equals("")) {
					viewHolder.mTvContent.setText(context
							.getString(R.string.content_file_not_upload_yet));
				} else {
					viewHolder.mTvContent.setText(priorityListItem
							.getLastModifiedDate());
				}

				/**
				 * Set file size
				 */
				long total_size = Long.valueOf(priorityListItem.getTotalSize());
				viewHolder.mTvTotalSize.setText(total_size / 1024 / 1024
						+ " MB");

				/**
				 * Set visible or invisible for Paused text, Resume button,
				 * Priority button
				 */
				if (priorityListItem.getPauseValue().equals("0")) {
					// if paused flag = 0
					// set Priority button state is Visible
					// set Paused text & Resume button state is Invisible
					if (position != 0) {
						viewHolder.mIbtnPriority.findViewWithTag(
								TAG_PRIORITY + position).setVisibility(
								View.VISIBLE);
					}
					viewHolder.mIbtnPause.findViewWithTag(TAG_PAUSE + position)
							.setVisibility(View.VISIBLE);
					viewHolder.mTvPaused.findViewWithTag(TAG_PAUSED + position)
							.setVisibility(View.INVISIBLE);
					viewHolder.mIbtnResume.findViewWithTag(
							TAG_RESUME + position)
							.setVisibility(View.INVISIBLE);
				} else if (priorityListItem.getPauseValue().equals("1")) {
					// if paused flag = 1
					// set Priority button state is Invisible
					// set Paused text & Resume button state is Visible
					viewHolder.mIbtnPriority.findViewWithTag(
							TAG_PRIORITY + position).setVisibility(
							View.INVISIBLE);
					viewHolder.mIbtnPause.findViewWithTag(TAG_PAUSE + position)
							.setVisibility(View.INVISIBLE);
					viewHolder.mTvPaused.findViewWithTag(TAG_PAUSED + position)
							.setVisibility(View.VISIBLE);
					viewHolder.mIbtnResume.findViewWithTag(
							TAG_RESUME + position).setVisibility(View.VISIBLE);
				}

				/**
				 * Pause will call an API to update the list in server to push
				 * the upload of paused clip to the last in the list and set
				 * paused flag to 1 to indicate termination of upload of this
				 * clip to the card..
				 */
				/**
				 * Pause is enabled only the size of file changes (status is
				 * refreshed every 7sec by the application)
				 */
				// Add Pause feature in here
				viewHolder.mIbtnPause.findViewWithTag(TAG_PAUSE + position)
						.setClickable(true);
				viewHolder.mIbtnPause.findViewWithTag(TAG_PAUSE + position)
						.setOnClickListener(new OnClickListener() {

							@Override
							public void onClick(View v) {
								/**
								 * When pause button is clicked, please display
								 * the following message : 淘Your video is
								 * re-queued for upload at the bottom of the
								 * priority list� Following that action, set
								 * the video send to last of the list
								 */
								onClickPause(position);
							}
						});

				/**
				 * Set on clicked for Priority button After clicked, change the
				 * order of this item is first
				 */
				viewHolder.mIbtnPriority.findViewWithTag(
						TAG_PRIORITY + position).setOnClickListener(
						new OnClickListener() {

							@Override
							public void onClick(View view) {
								onClickPriority(view, position,
										priorityListItem);
							}
						});

				/**
				 * Set on clicked for Resume button After clicked, - Paused flag
				 * set = 0 - Priority button appear again
				 */
				viewHolder.mIbtnResume
						.setOnClickListener(new OnClickListener() {

							@Override
							public void onClick(View view) {
								onClickResume(view, priorityListItem, position);
							}
						});
			}

			return convertView;
		}

		@Override
		public void unregisterDataSetObserver(DataSetObserver observer) {
			Toast.makeText(context, "unregisterDataSetObserver " + observer,
					Toast.LENGTH_SHORT).show();
			if (observer != null) {
				super.unregisterDataSetObserver(observer);
			}
		}

		public void add(int to, PriorityListItem items) {
		}

		public PriorityListItem get(int from) {
			return null;
		}

		private void findAndSubmitPauseItem(int position) {
			// Set Pause flag = 1
			mLlItem.get(position).setPauseValue("1");

			// Disappear item which already paused
			if (position != (mLlItem.size() - 1)) {
				// Remove this item, add to the last of array list
				// to send to the server
				mLlItem.addLast(mLlItem.get(position));
				mLlItem.remove(position);
			}

			// Notify the user that the order already
			// changed
			refreshPriorityListItemAdapter.notifyDataSetChanged();
		}

		private void onClickPause(int position) {
			// utils.PriorityList.IS_PAUSED_RESUMED_PRIORITIED = true;

			if (!mLlItem.isEmpty()) {
				Toast.makeText(context, context.getString(R.string.requeued),
						Toast.LENGTH_SHORT).show();

				findAndSubmitPauseItem(position);
			}
		}

		private void onClickPriority(View view, int position,
				PriorityListItem priorityListItem) {
			// Remove this item, add to the first of array list
			// to send to the server
			mLlItem.remove(position);
			mLlItem.addFirst(priorityListItem);

			// Notify the user that the order already
			// changed
			refreshPriorityListItemAdapter.notifyDataSetChanged();
		}

		private void onClickResume(View view,
				PriorityListItem priorityListItem, int position) {
			// utils.PriorityList.IS_PAUSED_RESUMED_PRIORITIED = true;

			/**
			 * Priority button appear again Paused text & Resume button
			 * disappear
			 */
			view.findViewWithTag(TAG_RESUME + position).setVisibility(
					View.INVISIBLE);

			/**
			 * Paused flag set = 0 again
			 */
			if (priorityListItem.getPauseValue().equals("1")) {
				mLlItem.get(position).setPauseValue("0");
			}

			// Notify the user that the order already
			// changed
			refreshPriorityListItemAdapter.notifyDataSetChanged();
		}

		public void remove(int from) {
		}
	}
}
